using Microsoft.Extensions.Logging;
using SumerCoreDevOps.Domain.Entities;
using SumerCoreDevOps.Infrastructure.Data;

namespace SumerCoreDevOps.Infrastructure.Identity;

/// <summary>
/// 权限管理器
/// </summary>
public class PermissionManager
{
    private readonly FreeSQLProvider _dbProvider;
    private readonly ILogger<PermissionManager> _logger;

    public PermissionManager(FreeSQLProvider dbProvider, ILogger<PermissionManager> logger)
    {
        _dbProvider = dbProvider;
        _logger = logger;
    }

    /// <summary>
    /// 创建权限
    /// </summary>
    public async Task<Permission> CreatePermissionAsync(
        string permissionCode,
        string permissionName,
        string? description = null,
        string? category = null,
        string? resourceType = null,
        string? resourceIdentifier = null,
        int sortOrder = 0,
        string? createdBy = null)
    {
        // 检查权限代码是否已存在
        var existingPermission = await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.PermissionCode == permissionCode)
            .FirstAsync();

        if (existingPermission != null)
        {
            throw new InvalidOperationException("权限代码已存在");
        }

        var permission = new Permission
        {
            PermissionCode = permissionCode,
            PermissionName = permissionName,
            Description = description,
            Category = category,
            ResourceType = resourceType,
            ResourceIdentifier = resourceIdentifier,
            IsSystem = false,
            SortOrder = sortOrder,
            CreatedAt = DateTime.UtcNow,
            CreatedBy = createdBy
        };

        await _dbProvider.Orm.Insert(permission).ExecuteAffrowsAsync();
        _logger.LogInformation("创建权限成功: {PermissionCode}", permissionCode);

        return permission;
    }

    /// <summary>
    /// 更新权限
    /// </summary>
    public async Task UpdatePermissionAsync(
        long permissionId,
        string? permissionName = null,
        string? description = null,
        string? category = null,
        string? resourceType = null,
        string? resourceIdentifier = null,
        int? sortOrder = null)
    {
        var permission = await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.Id == permissionId)
            .FirstAsync();

        if (permission == null)
        {
            throw new InvalidOperationException("权限不存在");
        }

        if (permission.IsSystem)
        {
            throw new InvalidOperationException("系统权限不允许修改");
        }

        if (!string.IsNullOrEmpty(permissionName))
        {
            permission.PermissionName = permissionName;
        }

        if (description != null)
        {
            permission.Description = description;
        }

        if (category != null)
        {
            permission.Category = category;
        }

        if (resourceType != null)
        {
            permission.ResourceType = resourceType;
        }

        if (resourceIdentifier != null)
        {
            permission.ResourceIdentifier = resourceIdentifier;
        }

        if (sortOrder.HasValue)
        {
            permission.SortOrder = sortOrder.Value;
        }

        permission.UpdatedAt = DateTime.UtcNow;

        await _dbProvider.Orm.Update<Permission>()
            .SetSource(permission)
            .ExecuteAffrowsAsync();

        _logger.LogInformation("更新权限成功: PermissionId={PermissionId}", permissionId);
    }

    /// <summary>
    /// 删除权限
    /// </summary>
    public async Task DeletePermissionAsync(long permissionId)
    {
        var permission = await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.Id == permissionId)
            .FirstAsync();

        if (permission == null)
        {
            throw new InvalidOperationException("权限不存在");
        }

        if (permission.IsSystem)
        {
            throw new InvalidOperationException("系统权限不允许删除");
        }

        // 检查是否有角色关联此权限
        var roleCount = await _dbProvider.Orm.Select<RolePermission>()
            .Where(rp => rp.PermissionId == permissionId)
            .CountAsync();

        if (roleCount > 0)
        {
            throw new InvalidOperationException($"权限被 {roleCount} 个角色使用，无法删除");
        }

        // 删除权限
        await _dbProvider.Orm.Delete<Permission>()
            .Where(p => p.Id == permissionId)
            .ExecuteAffrowsAsync();

        _logger.LogInformation("删除权限成功: PermissionId={PermissionId}", permissionId);
    }

    /// <summary>
    /// 根据 ID 获取权限
    /// </summary>
    public async Task<Permission?> GetPermissionByIdAsync(long permissionId)
    {
        return await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.Id == permissionId)
            .FirstAsync();
    }

    /// <summary>
    /// 根据权限代码获取权限
    /// </summary>
    public async Task<Permission?> GetPermissionByCodeAsync(string permissionCode)
    {
        return await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.PermissionCode == permissionCode)
            .FirstAsync();
    }

    /// <summary>
    /// 获取所有权限
    /// </summary>
    public async Task<List<Permission>> GetAllPermissionsAsync()
    {
        return await _dbProvider.Orm.Select<Permission>()
            .OrderBy(p => p.Category)
            .OrderBy(p => p.SortOrder)
            .ToListAsync();
    }

    /// <summary>
    /// 按分类获取权限
    /// </summary>
    public async Task<List<Permission>> GetPermissionsByCategoryAsync(string category)
    {
        return await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.Category == category)
            .OrderBy(p => p.SortOrder)
            .ToListAsync();
    }

    /// <summary>
    /// 获取权限分组（分类列表）
    /// </summary>
    public async Task<List<string>> GetPermissionCategoriesAsync()
    {
        var categories = await _dbProvider.Orm.Select<Permission>()
            .GroupBy(p => p.Category)
            .ToListAsync(g => g.Key);

        return categories.Where(c => !string.IsNullOrEmpty(c)).Select(c => c!).ToList();
    }

    /// <summary>
    /// 检查用户是否拥有指定权限
    /// </summary>
    public async Task<bool> CheckUserPermissionAsync(long userId, string permissionCode)
    {
        // 使用子查询方式检查用户权限
        var count = await _dbProvider.Orm.Select<Permission>()
            .Where(p => p.PermissionCode == permissionCode)
            .Where(p => _dbProvider.Orm.Select<RolePermission>()
                .InnerJoin<UserRole>((rp, ur) => rp.RoleId == ur.RoleId)
                .InnerJoin<Role>((rp, r) => rp.RoleId == r.Id)
                .InnerJoin<User>((rp, u) => true)
                .Where(rp => rp.PermissionId == p.Id)
                .Where<UserRole>(ur => ur.UserId == userId)
                .Where<Role>(r => r.IsEnabled == true)
                .Where<User>(u => u.Id == userId && u.IsEnabled == true && u.IsLocked == false)
                .Any())
            .CountAsync();

        return count > 0;
    }

    /// <summary>
    /// 检查用户是否拥有任一权限
    /// </summary>
    public async Task<bool> CheckUserAnyPermissionAsync(long userId, List<string> permissionCodes)
    {
        if (!permissionCodes.Any())
        {
            return false;
        }

        // 使用子查询方式检查用户是否拥有任一权限
        var count = await _dbProvider.Orm.Select<Permission>()
            .Where(p => permissionCodes.Contains(p.PermissionCode))
            .Where(p => _dbProvider.Orm.Select<RolePermission>()
                .InnerJoin<UserRole>((rp, ur) => rp.RoleId == ur.RoleId)
                .InnerJoin<Role>((rp, r) => rp.RoleId == r.Id)
                .InnerJoin<User>((rp, u) => true)
                .Where(rp => rp.PermissionId == p.Id)
                .Where<UserRole>(ur => ur.UserId == userId)
                .Where<Role>(r => r.IsEnabled == true)
                .Where<User>(u => u.Id == userId && u.IsEnabled == true && u.IsLocked == false)
                .Any())
            .CountAsync();

        return count > 0;
    }

    /// <summary>
    /// 检查用户是否拥有所有权限
    /// </summary>
    public async Task<bool> CheckUserAllPermissionsAsync(long userId, List<string> permissionCodes)
    {
        if (!permissionCodes.Any())
        {
            return true;
        }

        // 使用子查询方式检查用户是否拥有所有权限
        var count = await _dbProvider.Orm.Select<Permission>()
            .Where(p => permissionCodes.Contains(p.PermissionCode))
            .Where(p => _dbProvider.Orm.Select<RolePermission>()
                .InnerJoin<UserRole>((rp, ur) => rp.RoleId == ur.RoleId)
                .InnerJoin<Role>((rp, r) => rp.RoleId == r.Id)
                .InnerJoin<User>((rp, u) => true)
                .Where(rp => rp.PermissionId == p.Id)
                .Where<UserRole>(ur => ur.UserId == userId)
                .Where<Role>(r => r.IsEnabled == true)
                .Where<User>(u => u.Id == userId && u.IsEnabled == true && u.IsLocked == false)
                .Any())
            .Distinct()
            .CountAsync();

        return count == permissionCodes.Count;
    }

    /// <summary>
    /// 批量创建权限（用于初始化系统权限）
    /// </summary>
    public async Task<int> CreatePermissionsBatchAsync(List<Permission> permissions)
    {
        if (!permissions.Any())
        {
            return 0;
        }

        // 检查是否有重复的权限代码
        var codes = permissions.Select(p => p.PermissionCode).ToList();
        var existingPermissions = await _dbProvider.Orm.Select<Permission>()
            .Where(p => codes.Contains(p.PermissionCode))
            .ToListAsync();

        if (existingPermissions.Any())
        {
            var existingCodes = string.Join(", ", existingPermissions.Select(p => p.PermissionCode));
            throw new InvalidOperationException($"以下权限代码已存在: {existingCodes}");
        }

        await _dbProvider.Orm.Insert(permissions).ExecuteAffrowsAsync();
        _logger.LogInformation("批量创建权限成功: Count={Count}", permissions.Count);

        return permissions.Count;
    }
}
